Rebuild files if target directory is corrupt
authorAlex Crichton <alex@alexcrichton.com>
Mon, 8 Dec 2014 22:50:16 +0000 (14:50 -0800)
committerAlex Crichton <alex@alexcrichton.com>
Mon, 8 Dec 2014 22:50:16 +0000 (14:50 -0800)
If manual modifications have been made or if cargo/rustc died for some sort of
error, then we don't consider a target as being fresh. If any of the files
output by a target don't end up existing in the target directory (even if the
fingerprint says they do), then we consider the target not fresh.

cc #986

src/cargo/ops/cargo_rustc/fingerprint.rs
tests/test_cargo_compile.rs

index c842fbe89e21057521b9c004f2163a7a1b69d65b..455d5f44bfe927ad6ba90728e1dad75d26fa53d4 100644 (file)
@@ -63,8 +63,8 @@ pub fn prepare_target(cx: &mut Context, pkg: &Package, target: &Target,
     // First bit of the freshness calculation, whether the dep-info file
     // indicates that the target is fresh.
     let dep_info = dep_info_loc(cx, pkg, target, kind);
-    let are_files_fresh = use_pkg ||
-                          try!(calculate_target_fresh(pkg, &dep_info));
+    let mut are_files_fresh = use_pkg ||
+                              try!(calculate_target_fresh(pkg, &dep_info));
 
     // Second bit of the freshness calculation, whether rustc itself, the
     // target are fresh, and the enabled set of features are all fresh.
@@ -87,6 +87,9 @@ pub fn prepare_target(cx: &mut Context, pkg: &Package, target: &Target,
         for filename in try!(cx.target_filenames(target)).iter() {
             let dst = root.join(filename);
             cx.layout(pkg, kind).proxy().whitelist(&dst);
+            if are_files_fresh && !dst.exists() {
+                are_files_fresh = false;
+            }
 
             if target.get_profile().is_test() {
                 cx.compilation.tests.push((target.get_name().into_string(), dst));
index e36a4a09d1aabca37471f9428f1fc58f07a9ffa0..225c8c5bd44be73b74ff168541f0ba4d640fc8cc 100644 (file)
@@ -1496,3 +1496,20 @@ test!(example_bin_same_name {
     assert_that(&p.bin("foo"), existing_file());
     assert_that(&p.bin("examples/foo"), existing_file());
 })
+
+test!(compile_then_delete {
+    let p = project("foo")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "foo"
+            version = "0.0.1"
+            authors = []
+        "#)
+        .file("src/main.rs", "fn main() {}");
+
+    assert_that(p.cargo_process("run"), execs().with_status(0));
+    assert_that(&p.bin("foo"), existing_file());
+    fs::unlink(&p.bin("foo")).unwrap();
+    assert_that(p.process(cargo_dir().join("cargo")).arg("run"),
+                execs().with_status(0));
+})